package util

import (
	"bytes"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	url2 "net/url"
	"os"
	"regexp"
	"strings"
	"time"
)

func SetResponse(ctx *gin.Context, code int, isSuccess bool, data interface{}, msg string) {
	ctx.JSON(200, gin.H{
		"code":    code,
		"success": isSuccess,
		"data":    data,
		"msg":     msg,
	})
}

func SubtractArray(total []string, aim string) []string {
	var target []string
	aimArray := strings.Split(aim, ",")
	for _, value1 := range total {
		flag := false
		for _, value2 := range aimArray {
			if value1 == value2 {
				flag = true
				break
			}
		}
		if !flag {
			target = append(target, value1)
		}
	}
	return target
}

func Run(codeType, code string) string {
	switch codeType {
	case "cpp":
		out := RunCpp(code)
		return fmt.Sprintf("%g", out.(float64)*100)

	}
	return "0%"
}

func RunCpp(code string) interface{} {
	WriteFile(fmt.Sprintf("#ifndef _TEST_H_\n#define _TEST_H_\n%s\n#endif", code))
	var success, fail float64 = 0.0, 0.0
	for i := 0; i < 100; i++ {
		for j := 0; j < 100; j++ {
			fail++
		}
	}
	return success / (success + fail)
}

func WriteFile(code string) {
	filename := "E:\\code\\goPro\\BiYeProServer\\src\\util\\test\\cpp\\util.h"
	err := os.Remove(filename)
	if err != nil {
		return
	}
	var f *os.File
	var err1 error
	/***************************** 第一种方式: 使用 io.WriteString 写入文件 ***********************************************/
	if checkFileIsExist(filename) { //如果文件存在
		f, err1 = os.OpenFile(filename, os.O_CREATE, 0666) //打开文件
		fmt.Println("文件存在")
	} else {
		f, err1 = os.Create(filename) //创建文件
		fmt.Println("文件不存在")
	}
	_, err1 = io.WriteString(f, code) //写入文件(字符串)
	if err1 != nil {
		fmt.Println("系统错误")
		return
	}

	err = f.Close()
	if err != nil {
		fmt.Println("err for", err)
	}
}

/**
 * 判断文件是否存在  存在返回 true 不存在返回false
 */
func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

// 发送GET请求
// url：         请求地址
// response：    请求返回的内容
func Get(url string) string {
	// 超时时间：5秒
	client := &http.Client{Timeout: 5 * time.Second}
	resp, err := client.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	var buffer [512]byte
	result := bytes.NewBuffer(nil)
	for {
		n, err := resp.Body.Read(buffer[0:])
		result.Write(buffer[0:n])
		if err != nil && err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
	}

	return result.String()
}

func CommonGet(url string) string {
	res, err := http.Get(url)
	if err != nil {
		return ""
	}
	robots, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		return ""
	}
	return string(robots)
}

func Post(url string, data map[string]string) string {

	// 用url.values方式构造form-data参数
	formValues := url2.Values{}
	for key, value := range data {
		formValues.Set(key, value)
	}
	formDataStr := formValues.Encode()
	formDataBytes := []byte(formDataStr)
	formBytesReader := bytes.NewReader(formDataBytes)

	//生成post请求
	client := &http.Client{}
	//fmt.Println("check body",fmt.Sprintf("%+v",formBytesReader))
	req, err := http.NewRequest("POST", url, formBytesReader)
	if err != nil {
		// handle error
		log.Fatal("生成请求失败！", err)
		return ""
	}

	//注意别忘了设置header
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Cookie", "PHPSESSID=d1e29a5361nqk7rpqoe1ovkr92; expanded_dir_list=%3A%3Ahome%3Ajudge%3Asrc%3Aweb%3Aadmin; fm_current_root=%2Fhome%2Fjudge%2Fsrc%2Fweb%2F; resolveIDs=0; loggedon=d41d8cd98f00b204e9800998ecf8427e; order_dir_list_by=1A; lastlang=0")
	req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
	//fmt.Println(fmt.Sprintf("%+v",req))
	//Do方法发送请求
	resp, err := client.Do(req)

	defer resp.Body.Close()
	result, _ := ioutil.ReadAll(resp.Body)
	return string(result)
}

const loginUrl = "http://81.70.78.200/login.php"

func CronLogin() {
	result := Post(loginUrl, map[string]string{"user_id": "admin", "password": "d55d7dd75fc4756a8e236a25372d65a5"})
	fmt.Println(result)
}

func GetStatusData(result string) string {
	// "Problem ID ([\d]{4}) added!
	f := regexp.MustCompile(`<a href='problem.php?id=([\d]{4})'>`)
	params := f.FindStringSubmatch(result)
	if len(params) < 2 {
		return ""
	}
	return params[1]
}
